/**
 * OWASP Enterprise Security API (ESAPI)
 *
 * This file is part of the Open Web Application Security Project (OWASP)
 * Enterprise Security API (ESAPI) project. For details, please see
 * <a href="http://www.owasp.org/index.php/ESAPI">http://www.owasp.org/index.php/ESAPI</a>.
 *
 * Copyright (c) 2009 - The OWASP Foundation
 *
 * The ESAPI is published by OWASP under the BSD license. You should read and accept the
 * LICENSE before you use, modify, and/or redistribute this software.
 *
 * @author Arshan Dabirsiaghi <a href="http://www.aspectsecurity.com">Aspect Security</a>
 * @created 2009
 */
package org.owasp.esapi.waf.configuration;

import java.util.ArrayList;
import java.util.List;

import org.owasp.esapi.waf.rules.Rule;

/**
 * This class is the object model of the policy file. Also holds a number of constants
 * used throughout the WAF.
 *
 * @author Arshan Dabirsiaghi
 *
 */
public class AppGuardianConfiguration {

    /*
     * Fail modes (BLOCK blocks and logs the request, DONT_BLOCK simply logs)
     */
    public static final int LOG = 0;
    public static final int REDIRECT = 1;
    public static final int BLOCK = 2;

    /*
     * The operators.
     */
    public static final int OPERATOR_EQ = 0;
    public static final int OPERATOR_CONTAINS = 1;
    public static final int OPERATOR_IN_LIST = 2;
    public static final int OPERATOR_EXISTS = 3;


    /*
     * Default settings.
     */
    public static int DEFAULT_FAIL_ACTION = LOG;

    // TODO: use UTF-8
    public static String DEFAULT_CHARACTER_ENCODING = "ISO-8859-1";
    public static String DEFAULT_CONTENT_TYPE = "text/html; charset=" + DEFAULT_CHARACTER_ENCODING;

    /*
     * The JavaScript to redirect users to the default error page. Have
     * to use this because response.sendRedirect() can't have an arbitrary
     * response code and that is a requirement.
     */
    public static final String JAVASCRIPT_TARGET_TOKEN = "##1##";
    public static final String JAVASCRIPT_REDIRECT = "<html><body><script>document.location='" + JAVASCRIPT_TARGET_TOKEN + "';</script></body></html>";

    /*
     * Fail response settings.
     */
    private String defaultErrorPage;
    private int defaultResponseCode;

    private boolean forceHttpOnlyFlagToSession = false;
    private boolean forceSecureFlagToSession = false;

    private String sessionCookieName;

    public String getSessionCookieName() {
        return sessionCookieName;
    }

    public void setSessionCookieName(String sessionCookieName) {
        this.sessionCookieName = sessionCookieName;
    }

    /*
     * The object-level rules encapsulated by the stage in which they are executed.
     */
    private List<Rule> beforeBodyRules;
    private List<Rule> afterBodyRules;
    private List<Rule> beforeResponseRules;
    private List<Rule> cookieRules;

    public AppGuardianConfiguration() {
        beforeBodyRules = new ArrayList<Rule>();
        afterBodyRules = new ArrayList<Rule>();
        beforeResponseRules = new ArrayList<Rule>();
        cookieRules = new ArrayList<Rule>();
    }

    public String getDefaultErrorPage() {
        return defaultErrorPage;
    }

    public void setDefaultErrorPage(String defaultErrorPage) {
        this.defaultErrorPage = defaultErrorPage;
    }

    public int getDefaultResponseCode() {
        return defaultResponseCode;
    }

    public void setDefaultResponseCode(int defaultResponseCode) {
        this.defaultResponseCode = defaultResponseCode;
    }


    public List<Rule> getBeforeBodyRules() {
        return beforeBodyRules;
    }

    public List<Rule> getAfterBodyRules() {
        return afterBodyRules;
    }

    public List<Rule> getBeforeResponseRules() {
        return beforeResponseRules;
    }

    public List<Rule> getCookieRules() {
        return cookieRules;
    }

    public void addBeforeBodyRule(Rule r) {
        beforeBodyRules.add(r);
    }

    public void addAfterBodyRule(Rule r) {
        afterBodyRules.add(r);
    }

    public void addBeforeResponseRule(Rule r) {
        beforeResponseRules.add(r);
    }

    public void addCookieRule(Rule r) {
        cookieRules.add(r);
    }

    public void setApplyHTTPOnlyFlagToSessionCookie(boolean shouldApply) {
        forceHttpOnlyFlagToSession = shouldApply;
    }

    public void setApplySecureFlagToSessionCookie(boolean shouldApply) {
        forceSecureFlagToSession = shouldApply;
    }

    public boolean isUsingHttpOnlyFlagOnSessionCookie() {
        return forceHttpOnlyFlagToSession;
    }

    public boolean isUsingSecureFlagOnSessionCookie() {
        return forceSecureFlagToSession;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder( "WAF Configuration\n" );
        sb.append( "Before body rules:\n" );
        for ( Rule rule : beforeBodyRules ) sb.append( "  " + rule.toString() + "\n" );
        sb.append( "After body rules:\n" );
        for ( Rule rule : afterBodyRules ) sb.append( "  " + rule.toString() + "\n" );
        sb.append( "Before response rules:\n" );
        for ( Rule rule : beforeResponseRules ) sb.append( "  " + rule.toString() + "\n" );
        sb.append( "Cookie rules:\n" );
        for ( Rule rule : cookieRules ) sb.append( "  " + rule.toString() + "\n" );
        return sb.toString();
    }
}
